package com.mar.tech.unify.service.database;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.mysqlclient.MySQLPool;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.RowIterator;
import io.vertx.sqlclient.RowSet;
import io.vertx.sqlclient.Tuple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * Description: 数据库处理 .<br>
 *
 * @author m-xy
 *     Created By 2019/12/3 18:29
 */
public class DatabaseServiceImpl implements DatabaseService {
  private final static Logger logger = LoggerFactory.getLogger(DatabaseServiceImpl.class);
  private MySQLPool jdbcClient;

  public DatabaseServiceImpl(MySQLPool jdbcClient, Handler<AsyncResult<DatabaseService>> readyHandler) {
    this.jdbcClient = jdbcClient;
    readyHandler.handle(Future.succeededFuture(this));
  }

  @Override
  public DatabaseService query(String sql, JsonArray param, Handler<AsyncResult<JsonArray>> resultHandler) {
    if (param == null || param.size() == 0) {
      writeLog(sql, "无参数");
      jdbcClient.query(sql).execute(res -> {
        if (res.failed()) {
          logger.error("Database query error", res.cause());
          resultHandler.handle(Future.failedFuture(res.cause()));
          return;
        }
        resultHandler.handle(Future.succeededFuture(ofRowSet(res.result())));
      });
      return this;
    } else {
      writeLog(sql, param.toString());
      jdbcClient.preparedQuery(sql).execute(Tuple.tuple(param.getList()), res -> {
        if (res.failed()) {
          logger.error("Database query error", res.cause());
          resultHandler.handle(Future.failedFuture(res.cause()));
          return;
        }
        resultHandler.handle(Future.succeededFuture(ofRowSet(res.result())));
      });
      return this;
    }
  }

  /**
   * 记录日志.
   *
   * @param sql
   * @param param
   */
  private void writeLog(String sql, String param) {
    logger.debug("\n    [SQL语句]: {}\n    [SQL参数]: {}\n", sql, param);
  }

  /**
   * 转换为 JsonArray
   *
   * @param rows
   * @return
   */
  private JsonArray ofRowSet(RowSet<Row> rows) {
    RowIterator<Row> iterator = rows.iterator();
    JsonArray jsonArray = new JsonArray();
    while (iterator.hasNext()) {
      Row row = iterator.next();
      int size = row.size();
      JsonObject jsonObject = new JsonObject();
      for (int i = 0; i < size; i++) {
        Object rowValue = row.getValue(i);
        if (rowValue instanceof LocalDate) {
          jsonObject.put(row.getColumnName(i), rowValue.toString());
          continue;
        }
        if (rowValue instanceof LocalDateTime) {
          jsonObject.put(row.getColumnName(i), rowValue.toString());
          continue;
        }
        jsonObject.put(row.getColumnName(i), rowValue);
      }
      jsonArray.add(jsonObject);
    }
    return jsonArray;
  }
}
